/**
 * 定时任务只是提供定时触发执行某任务开关，所有任务共享timer的线程池。
 * 如果任务需要在独立线程里执行，需要由实现者自行实现。
 */

package ms.core.serv.tool;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import lombok.Data;
import ms.core.tool.Log4j2Tool;
import ms.core.tool.StrTool;
import ms.core.tool.StreamTool;

public class TaskLoader {
	private static String fileName = "/config/task.xml";
	private static List<Timer> timers = null;
	private static List<Task> tasks = null;

	private static void loadTaskConf() {
		tasks = new ArrayList<>();
		try{
			InputStream in = StreamTool.loadFileToStream(TaskLoader.class, fileName);
			SAXReader reader = new SAXReader();
			Document doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> items = root.elements();
			for(Element item : items){
				Task task = new Task();
				task.setTaskName(item.attributeValue("taskName"));
				task.setClassName(item.attributeValue("className"));
				task.setInterval(StrTool.strToInt(item.attributeValue("interval"), 1000));
				task.setDescription(item.attributeValue("desc"));
				task.setEnable("true".equalsIgnoreCase(item.attributeValue("enable")));
				tasks.add(task);
			}
			in.close();
		} catch (Exception e) {
			Log4j2Tool.error(TaskLoader.class, e);
		}
	}
	
	private static void startTask() {
		timers = new ArrayList<>();
		for(int i=0; i<tasks.size(); i++) {
			if (tasks.get(i).isEnable()) {
				try {
					Class<?> cls = Class.forName(tasks.get(i).getClassName());
					Constructor<?> constructor = cls.getConstructor(Task.class);
					TimerTask tmTsk = (TimerTask) constructor.newInstance(tasks.get(i));
					Timer timer = new Timer(true);
					timer.schedule(tmTsk, new Date(), tasks.get(i).getInterval());
					timers.add(timer);
				} catch(Exception e) {
					Log4j2Tool.error(TaskLoader.class, tasks.get(i).getTaskName()+"定时任务加载失败!");
				}
			}
		}
	}
	
	private static void stopTask() {
		for(Timer t: timers) t.cancel();
	}
	
	public static void start() {
		loadTaskConf();
		startTask();
	}
	
	public static void stop() {
		stopTask();
	}
	
	@Data
	public static class Task {
		private String taskName;		//taskId
		private String className;		//task class name
		private int interval;			//milliseconds of execute cycle
		private boolean enable;			//if task is enable true or false
		private String description;		//task description
	}		
}
